ALBとCLBのアクセスログを保存するS3バケットポリシーをCloudFormation(YAML)で書いてみた
はじめに
Application Load BalancerやClassic Load Balancerのアクセスログ機能を有効化すると、S3バケットにログを格納できます。 バケットにはポリシーを設定する必要があります。 ポリシーはALBのユーザーガイドやCLBのユーザーガイドに記載されています。 AWSコンソールでログ有効化する場合、"この場所の作成"を選択するとポリシーが設定されたS3バケットが作成されるため、あまりポリシーを意識することはないかもしれません。
今回は、YAML形式のCloudFormationテンプレートを作る際にバケットポリシーの書き方にはまったので、共有します。
テンプレート
テンプレートでは、バケットポリシーが設定されたS3バケットを作成します。 ELBの種類(ALB,CLB)に関わらず必要なポリシーは同一です。
AWSTemplateFormatVersion: 2010-09-09 Description: ELB Bucket Test Mappings: S3Config: us-east-1: BucketPrincipal: "127311923021" us-east-2: BucketPrincipal: "033677994240" us-west-1: BucketPrincipal: "027434742980" us-west-2: BucketPrincipal: "797873946194" ca-central-1: BucketPrincipal: "985666609251" eu-west-1: BucketPrincipal: "156460612806" eu-central-1: BucketPrincipal: "054676820928" eu-west-2: BucketPrincipal: "652711504416" ap-northeast-1: BucketPrincipal: "582318560864" ap-northeast-2: BucketPrincipal: "600734575887" ap-southeast-1: BucketPrincipal: "114774131450" ap-southeast-2: BucketPrincipal: "783225319266" ap-south-1: BucketPrincipal: "718504428378" sa-east-1: BucketPrincipal: "507241528517" us-gov-west-1: BucketPrincipal: "048591011584" cn-north-1: BucketPrincipal: "638102146993" Resources: ELBLogBucket: Type: "AWS::S3::Bucket" Properties: BucketName: !Join [ "-", [ elblog , Ref: "AWS::AccountId" ] ] BucketPolicyELBLogBucket: Type: "AWS::S3::BucketPolicy" Properties: Bucket: Ref: "ELBLogBucket" PolicyDocument: Id: "Allow-Put-ELB-logs" Version: "2012-10-17" Statement: - Sid: "Stmt1429136633762" Action: - "s3:PutObject" Effect: "Allow" Resource: Fn::Join: - "" - - "arn:aws:s3:::" - Ref: "ELBLogBucket" - "/AWSLogs/" - Ref: AWS::AccountId - "/*" Principal: AWS: !FindInMap [ S3Config, Ref: "AWS::Region", BucketPrincipal ]
解説
リソース
ELBLogBucketがS3バケット、BucketPolicyELBLogBucketがバケットポリシーに関する記述です。
プレフィックスの指定
ELBではアクセスログを配置するS3プレフィックスを指定できます。バケット名/my-appといった形です。 プレフィックスを指定する場合、バケットポリシーの修正が必要です。 "/AWSLogs/"を"/my-app/AWSLogs/"のようにします。 上記テンプレートはプレフィックスを指定しない前提です。
自アカウントIDの指定
"AWS::AccountId"などを擬似パラメーターといいます。 「Ref: AWS::AccountId」とすると、スタックが作成されているアカウントのアカウントIDを返します。
PrincipalでのELBアカウントIDの指定
Principalでは、ELBを配置するリージョンに応じてAWSアカウントIDを指定します。 東京リージョンの場合、"582318560864"、オレゴンリージョンの場合、"797873946194"といった形です。 テンプレートでは、Create Stackしたリージョンと同じアカウントIDがPrincipalに入るようにしました。 東京リージョンでCreate Stackすると、"582318560864"がPrincipalに記載されます。 この仕組みにはMappingsセクション、FindInMap組み込み関数、AWS::Region擬似パラメーターを使いました。
バケットの名前
Join組み込み関数を使って、elblog-アカウントIDという名前のバケットが作成されるようにしました。 実環境でお使いの場合、適宜変更してください。
おわりに
YAML形式のCloudFormationテンプレートを作る際にはまったので、共有しました。 同様に、はまったかたのお役に立てれば嬉しいです。